home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Lib / or / or_check.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  9.6 KB  |  391 lines

  1. /* or_check.c: check and normalise or names */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Lib/or/RCS/or_check.c,v 6.0 1991/12/18 20:23:08 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Lib/or/RCS/or_check.c,v 6.0 1991/12/18 20:23:08 jpo Rel $
  9.  *
  10.  * $Log: or_check.c,v $
  11.  * Revision 6.0  1991/12/18  20:23:08  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "util.h"
  19. #include "or.h"
  20. #include "table.h"
  21. #include <isode/cmd_srch.h>
  22.  
  23. extern CMD_TABLE ortbl_rfc822ddas[];
  24. extern char     *or_tbl;
  25. static Table    *tb_or;
  26. char            or_error[BUFSIZ] = "";
  27.  
  28.  
  29. /* ---------------------  Begin  Routines  -------------------------------- */
  30.  
  31.  
  32. /* --- *** ---
  33. or_check (or, buf, buf_type, locname)  where:
  34.     or              -       what is being checked
  35.     buf             -       what is returned
  36.     buf_type        -       Channel or local
  37.     lsubdom        -    local proferred table
  38.     replace        -    if synonym'd place to put replacement or
  39. --- *** --- */
  40.  
  41. #define    MAX_NUM_REPLACES    25
  42. #define WILDCARD        "*"
  43.  
  44. static int or_fill_wilds_and_swap();
  45.  
  46. static int allRFC822DDA (or)
  47. OR_ptr    or;
  48. {
  49.     while (or != NULLOR
  50.            && or->or_type == OR_DD
  51.            && cmd_srch(or->or_ddname, ortbl_rfc822ddas) != -1)
  52.         or = or->or_next;
  53.     if (or == NULLOR)
  54.         return TRUE;
  55.     return FALSE;
  56. }
  57.  
  58. int or_check (or, buf, buf_type, lsubdom, replace, lastMatch)
  59. OR_ptr          *or;
  60. char            *buf;
  61. int             *buf_type;
  62. char        **lsubdom;
  63. char        **replace;
  64. OR_ptr        *lastMatch;
  65. {
  66.     OR_ptr          tptr,
  67.             sptr,
  68.             current_ptr,
  69.             tree;
  70.     char            current_val[LINESIZE],
  71.             tbuf[LINESIZE],
  72.             tracebuf[LINESIZE],
  73.             *oargv[10];
  74.     int             oargc;
  75.     char        first_lookup[BUFSIZ];
  76.     int        postReplace = FALSE,
  77.             num_replaces = 0,
  78.             aliased = FALSE;
  79.  
  80.     PP_DBG (("Lib/or_chk()"));
  81.  
  82.     first_lookup[0] ='\0';
  83.     if (replace != (char **) NULL)
  84.         *replace = NULLCP;
  85.  
  86.     *lastMatch = NULLOR;
  87.     *lsubdom = NULLCP;
  88.     if ((tptr = loc_ortree) == NULLOR) {
  89.         PP_LOG (LLOG_EXCEPTIONS, ("Lib/or_chk: loc_ortree missing"));
  90.         return NOTOK;
  91.     }
  92.  
  93.     if ((current_ptr = tree = or_tdup(*or)) == NULLOR)
  94.         return or_lose ("No OR specified for checking");
  95.  
  96.     
  97.     if (tb_or == NULLTBL) {
  98.         if ((tb_or = tb_nm2struct (or_tbl)) == NULLTBL)
  99.             return or_lose ("No or table!!!");
  100.     }
  101.  
  102.     or_or2std (tree, tracebuf, FALSE);
  103.     PP_TRACE (("Lib/or_chk's tracebuf: '%s'", tracebuf));
  104.  
  105.     buf[0] = '\0';
  106.  
  107.     for (;;) {
  108.         or_or2dmn (NULLOR, current_ptr, current_val);
  109.         PP_DBG (("Lib/or_chk: Checking part: '%s'", current_val));
  110.  
  111.  
  112.         if (tb_k2val (tb_or, current_val, tbuf, TRUE) != OK) {
  113.             char    *holder = NULLCP;
  114.             char    prev_current_val[LINESIZE];
  115.             (void) strcpy(prev_current_val, current_val);
  116.             if (current_ptr != NULLOR) {
  117.                 holder = current_ptr -> or_value;
  118.                 current_ptr -> or_value = strdup(WILDCARD);
  119.                 or_or2dmn (NULLOR, current_ptr, current_val);
  120.             }
  121.             if (current_ptr != NULLOR
  122.                 && tb_k2val (tb_or, current_val, tbuf, TRUE) == OK)  {
  123.                 if (holder)
  124.                     free(holder);
  125.             } else {
  126.                 if (current_ptr) {
  127.                     free(current_ptr -> or_value);
  128.                     current_ptr -> or_value = holder;
  129.                 }
  130.                 if (buf[0] == '\0' && postReplace == FALSE) {
  131.                     char    *orargv[10], tmp[BUFSIZ];
  132.                     char    *dollar;
  133.                     (void) strcpy(current_val, prev_current_val);
  134.                     PP_DBG (("Lib/or_chk: Check failed '%s' '%s'",
  135.                          current_val, tracebuf));
  136.                     if (first_lookup[0] != '\0')
  137.                         or_or2std(or_lastpart(tree), tmp, FALSE);
  138.                     else
  139.                         tmp[0] = '\0';
  140.  
  141.                     if (sstr2arg (current_val, 9, orargv, ".")) {
  142.                         if ((dollar = index (orargv[0], '$')) != NULLCP)
  143.                             *dollar = ' ';
  144.                         if (first_lookup[0] == '\0'
  145.                             || lexequ(first_lookup, tmp) == 0) 
  146.                             (void) or_lose (
  147.                                     "Unknown '%s' in '%s'",
  148.                                     orargv[0], tracebuf);
  149.                         else
  150.                             (void) or_lose (
  151.                                     "Unknown '%s' in '%s' (aka '%s')",
  152.                                     orargv[0], tmp, first_lookup);
  153.                     }
  154.                     else {
  155.                         if (first_lookup[0] == '\0'
  156.                             || lexequ(first_lookup, tmp) == 0)
  157.                             (void) or_lose (
  158.                                     "Unknown '%s' in '%s'",
  159.                                     current_val, tracebuf);
  160.                         else
  161.                             (void) or_lose (
  162.                                     "Unknown '%s' in '%s' (aka '%s')",
  163.                                     current_val, tmp, first_lookup);
  164.                     }
  165.                     return NOTOK;
  166.                 }
  167.                 else if (buf[0] == '\0' && postReplace == TRUE) {
  168.                     /* no direct match with replacement */
  169.                     /* rewind checking and start again */
  170.                     current_ptr = tree;
  171.                     postReplace = FALSE;
  172.                     continue;
  173.                 }
  174.                 else {
  175.                     if (or_fill_wilds_and_swap(or, tree) != OK) {
  176.                         (void) or_lose ("Local wildcard OR problems for '%s'",
  177.                              tracebuf);
  178.                         return NOTOK;
  179.                     }
  180.                     or_chk_admd(or);
  181.                     return OK;
  182.                 }
  183.             }
  184.         }
  185.  
  186.         postReplace = FALSE;
  187.  
  188.         PP_DBG (("Lib/or_chk: Hit: '%s'", tbuf));
  189.  
  190.         /* --- Have found a pointer --- */
  191.         oargc = sstr2arg (tbuf, 9, oargv, " \t\n,");
  192.  
  193.         if (lexequ (oargv[0], "valid") == 0) {
  194.             buf[0] = '\0';
  195.             current_ptr = current_ptr -> or_next;
  196.             continue;
  197.         }
  198.  
  199.  
  200.         if (lexequ (oargv[0], "local") == 0) {
  201.             /* --- This is local - map rest to buf --- */
  202.             if (current_ptr -> or_next == NULLOR) 
  203.                 return or_lose (
  204.                         "local entry found - but no more components '%s'",
  205.                         tracebuf);
  206.             else if (allRFC822DDA(current_ptr -> or_next) == TRUE) {    
  207.                 tptr = current_ptr->or_next;
  208.                 tptr->or_prev = NULLOR;
  209.                 or_or2std(tptr, buf, TRUE);
  210.                 tptr->or_prev = current_ptr;
  211.                 return or_lose(
  212.                            "unknown local user '%s'",
  213.                            buf);
  214.             }
  215.  
  216.             *lastMatch = tptr = current_ptr;
  217.             current_ptr = current_ptr -> or_next;
  218.             current_ptr ->  or_prev = NULLOR;
  219.  
  220.             if (current_ptr -> or_type <= OR_OU
  221.                 || (or_getpn (current_ptr, buf) == FALSE))
  222.                 or_or2std (current_ptr, buf, TRUE);
  223.                 
  224.             current_ptr -> or_prev = tptr;
  225.             *buf_type = OR_ISLOCAL;
  226.  
  227.             PP_TRACE (("Lib/or_chk: Returning local: '%s' '%s' ",
  228.                 buf, tracebuf));
  229.             if (oargc > 1)
  230.                 *lsubdom = strdup (oargv[1]);
  231.             continue;
  232.         }  /* --- end of if local --- */
  233.  
  234.  
  235.         if (oargc < 2) 
  236.             return or_lose ("Format error in OR table '%s' '%s'",
  237.                     current_val, tracebuf);
  238.  
  239.  
  240.         if (lexequ (oargv[0], "mta") == 0) {
  241.             (void) strcpy (buf, oargv[1]);
  242.             *buf_type = OR_ISMTA;
  243.             *lastMatch = current_ptr;
  244.             current_ptr = current_ptr -> or_next;
  245.             continue;
  246.         }
  247.  
  248.  
  249.         if (lexequ (oargv[0], "realalias") == 0) {
  250.             /* --- invalidate previous hits --- */
  251.             buf[0] = '\0';
  252.             postReplace = TRUE;
  253.             aliased = TRUE;
  254.             if (++num_replaces > MAX_NUM_REPLACES)
  255.                 return or_lose ("Too many aliases/synonyms when resolving '%s'",
  256.                         tracebuf);
  257.  
  258.             if ((tptr = or_dmn2or (oargv[1])) == NULLOR)
  259.                 return or_lose ("Invalid syntax alias '%s' '%s'",
  260.                         oargv[1], tracebuf);
  261.             
  262.             if (first_lookup[0] == '\0')
  263.                 or_or2std(or_lastpart(tree), first_lookup, FALSE);
  264.  
  265.             /* --- free off old head --- */
  266.             if ((sptr = current_ptr -> or_next) != NULLOR) {
  267.                 sptr -> or_prev         = NULLOR;
  268.                 current_ptr -> or_next  = NULLOR;
  269.             } 
  270.             or_free (tree);
  271.  
  272.             /* --- add in the new stuff --- */
  273.             tree                     = tptr;
  274.             current_ptr             = or_lastpart (tptr);
  275.  
  276.             if (sptr != NULLOR) {
  277.                 /* --- add back in the rest of old stuff */
  278.                 if (sptr -> or_type < current_ptr -> or_type)
  279.                     return or_lose ("Alias out of order '%s' '%s'",
  280.                             oargv[1], tracebuf);
  281.  
  282.                 current_ptr -> or_next  = sptr;
  283.                 sptr -> or_prev         = current_ptr;
  284.             }
  285.             continue;
  286.         }  /* --- end of if alias --- */
  287.  
  288.         if (lexequ (oargv[0], "synonym") == 0
  289.             || lexequ (oargv[0], "alias") == 0) {
  290.             /* --- invalidate previous hits --- */
  291.             buf[0] = '\0';
  292.             postReplace = TRUE;
  293.  
  294.             if (++num_replaces > MAX_NUM_REPLACES)
  295.                 return or_lose ("Too many aliases/synonyms when resolving '%s'",
  296.                     tracebuf);
  297.  
  298.             if ((tptr = or_dmn2or (oargv[1])) == NULLOR)
  299.                 return or_lose (
  300.                     "Invalid syntax alias '%s' '%s'",
  301.                     oargv[1], tracebuf);
  302.             
  303.             if (first_lookup[0] == '\0')
  304.                 or_or2std(or_lastpart(tree), first_lookup, FALSE);
  305.  
  306.             /* --- free off old head --- */
  307.             if ((sptr = current_ptr -> or_next) != NULLOR) {
  308.                 sptr -> or_prev         = NULLOR;
  309.                 current_ptr -> or_next  = NULLOR;
  310.             } 
  311.             or_free (tree);
  312.  
  313.             /* --- add in the new stuff --- */
  314.             tree                     = tptr;
  315.             current_ptr             = or_lastpart (tptr);
  316.  
  317.             if (sptr != NULLOR) {
  318.                 /* --- add back in the rest of old stuff */
  319.                 if (sptr -> or_type < current_ptr -> or_type)
  320.                     return or_lose (
  321.                             "Alias out of order '%s' '%s'",
  322.                             oargv[1], tracebuf);
  323.  
  324.                 current_ptr -> or_next  = sptr;
  325.                 sptr -> or_prev         = current_ptr;
  326.             }
  327.             if (aliased == FALSE
  328.                 && replace != (char **) NULL) {
  329.                 char    tmp[BUFSIZ];
  330.                 if (*replace != NULLCP)
  331.                     free(*replace);
  332.                 or_or2std(or_lastpart(tree), tmp, FALSE);
  333.                 *replace = strdup(tmp);
  334.             }
  335.             continue;
  336.         }  /* --- end of if synonym --- */
  337.  
  338.         return or_lose ("Unknown alias type '%s' '%s'",
  339.                 oargv[1], tracebuf);
  340.     }  /* end of for */
  341. }
  342.  
  343. /*   */
  344.  
  345. static int or_fill_wilds_and_swap(por, tree)
  346. OR_ptr    *por, tree;
  347. {
  348.     /* take WILDCARDS from por and replace in tree */
  349.     /* then swap trees */
  350.  
  351.     OR_ptr    ixor, ixt;
  352.     int    numOU1 = 0, numOU2 = 0;
  353.  
  354.     for (ixt = tree, ixor = *por; ixt != NULLOR; ixt = ixt->or_next) {
  355.         if (lexequ(ixt->or_value, WILDCARD) == 0) {
  356.             if (ixt->or_type == OR_OU) {
  357.                 while (ixor != NULLOR
  358.                        && (ixor -> or_type != ixt -> or_type
  359.                        || numOU1 != numOU2)) {
  360.                     if (ixor -> or_type == OR_OU)
  361.                         numOU2++;
  362.                     ixor = ixor -> or_next;
  363.                 }
  364.             } else {
  365.                 while (ixor != NULLOR && 
  366.                        ixor -> or_type != ixt -> or_type) {
  367.                     if (ixor -> or_type == OR_OU)
  368.                         numOU2++;
  369.                     ixor = ixor -> or_next;
  370.                 }
  371.             }
  372.             if (ixor == NULLOR) {
  373.                 PP_LOG (LLOG_EXCEPTIONS,
  374.                     ("Unable to find original valure for wildcard '%s'",
  375.                      or_type2name(ixt -> or_type)));
  376.                 return NOTOK;
  377.             }
  378.             free (ixt -> or_value);
  379.             ixt -> or_value = strdup(ixor -> or_value);
  380.             ixor = ixor -> or_next;
  381.         }
  382.         if (ixt->or_type == OR_OU)
  383.             numOU1++;
  384.     }
  385.  
  386.     or_free(*por);
  387.  
  388.     *por = tree;
  389.     return OK;
  390. }
  391.